import Config from "./Config";
import Model from "./Model";
import MetaballMgr from "./MetaballMgr";
import WxUtil from "./WxUtil";

const { ccclass, property } = cc._decorator;
@ccclass
export default class GameDrag extends cc.Component {

    @property(cc.Node)
    grac: cc.Node = null;

    @property(cc.Prefab)
    Cup: cc.Prefab = null;

    @property(cc.Node)
    dotLine: cc.Node = null;

    @property(cc.Node)
    waterPipe: cc.Node = null;

    @property(cc.Node)
    waterContainer: cc.Node = null;

    @property(cc.Node)
    metaBall: cc.Node = null;

    @property(cc.Node)
    ground: cc.Node = null;

    @property(cc.Prefab)
    Ball: cc.Prefab = null;

    @property(cc.Prefab)
    TopUI: cc.Prefab= null;;

    @property(cc.Prefab)
    BottomUI: cc.Prefab= null;;

    @property(cc.Prefab)
    Brick: cc.Prefab= null;;

    touchX: number = 0
    touchY: number = 0

    cup: cc.Node;

    draw: cc.Graphics;

    lock: boolean = false;

    totalWater = 44
    waterCount = 0
    over:boolean=false;

    waters:Array<cc.Node>;
    
    @property({type:cc.AudioClip})
    waterClip: cc.AudioClip= null;;

    waterSoundDelay=0.2;
    waterSoundDelayCount=10;

    onLoad() {
        Config.init()
        //开启物理效果
        cc.director.getPhysicsManager().enabled = true
        cc.director.getPhysicsManager().gravity = new cc.Vec2(0, -800);
       // cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_jointBit | cc.PhysicsManager.DrawBits.e_shapeBit;

        this.draw = this.grac.getComponent(cc.Graphics);

        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this)
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this)
        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this)
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this)

        this.createWorld()

        var top=cc.instantiate(this.TopUI)
        this.node.addChild(top)

        this.metaBall.getComponent(MetaballMgr).waters=this.waters;
        this.node.getChildByName('gameTip').active=Model.game.selectedLevel==1
       
    }
    createWorld() {
        //createCup        
        var level = Model.game.selectedLevel;
        var data = Config.dragLevels[level];
        var cupPos = data[0]

        var cup = cc.instantiate(this.Cup);
        cup.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic;
        cup.x = cupPos[0]
        cup.y = cupPos[1]
        this.node.addChild(cup)

        var cupData = Config.cupDatas[1]
        for (var i = 0; i < cupData.polygonColliderList.length; i++) {
            cup.addComponent(cc.PhysicsPolygonCollider)
        }
        //添加改变后，要用apply
        var allCollider = cup.getComponents(cc.PhysicsPolygonCollider);
        for (i = 0; i < allCollider.length; i++) {
            var tempC = allCollider[i];
            tempC.points = cupData.polygonColliderList[i]
            tempC.density = 2
            tempC.apply()
        }
        this.cup = cup

        this.dotLine.x = data[2][0]
        this.dotLine.y = data[2][1]

        this.waterPipe.x = data[1][0]
        this.waterPipe.y = data[1][1]

         //bricks
         for (var i = 3; i < data.length; i++) {
            var brickType = data[i][0]
            var brick:cc.Node = cc.instantiate(this.Brick)
            brick.x = data[i][1]
            brick.y = data[i][2]
            
            if (brickType == 1)//矩形
            {
                brick.setContentSize(cc.size(data[i][3], data[i][4]))
                brick.getComponent(cc.PhysicsBoxCollider).size = cc.size(cc.size(data[i][3], data[i][4]))
                brick.getComponent(cc.PhysicsBoxCollider).apply()
            }
            brick.angle = -data[i][5]
            this.node.addChild(brick)
        }

         this.ground.getComponent(cc.RigidBody).onBeginContact = (contact, selfCollider, otherCollider) => {
             this.onBeginContact(contact, selfCollider, otherCollider)
         }

         this.waters=[]
    }
    onTouchStart(e) {
        if (this.lock) return
        var pos = e.getLocation();
        pos = this.node.convertToNodeSpaceAR(pos)
        this.touchX = pos.x;
        this.touchY = pos.y;
        this.draw.moveTo(pos.x, pos.y)
    }
    onTouchMove(e) {
        if (this.lock) return
        var pos = e.getLocation();
        pos = this.node.convertToNodeSpaceAR(pos)
        this.draw.clear()
        this.draw.moveTo(this.touchX, this.touchY)
        this.draw.lineTo(pos.x, pos.y)
        this.draw.stroke()

    }
    onTouchEnd(e) {
        if (this.lock) return
        this.lock = true
        this.draw.clear()
        var center = this.cup.getComponent(cc.RigidBody).getWorldCenter();
        var pos = e.getLocation();
        pos = this.node.convertToNodeSpaceAR(pos)
        var dx = pos.x - this.touchX
        var dy = pos.y - this.touchY
        //var angle=Math.atan2(dy,dx);
        var dis = Math.sqrt(dx * dx + dy * dy);
        var speed = 20 * dis
        var v = cc.v2(dx / dis * speed, dy / dis * speed)

        this.cup.getComponent(cc.RigidBody).applyLinearImpulse(v, cc.v2(center.x, center.y - 30), true);
        var sign = dx < 0 ? 1 : -1
        this.cup.getComponent(cc.RigidBody).applyAngularImpulse(dis * 1000 * sign, true);

        this.schedule(this.startCheck, 0.016)
    }

    start() {
        WxUtil.destroyBanner()
    }
    startCheck() {
        if (this.lock) {
            if (this.cup.x < -455 || this.cup.x > 830||this.cup.y<-500) {                
                this.gameLose()
                return
            }
            if (this.cup.getComponent(cc.RigidBody).awake == false) {
                this.unschedule(this.startCheck)
                // if (Math.abs(this.cup.rotation) > 70) {
                //    this.gameLose()
                // } else {
                    this.startDropWater()
              //  }
            }
        }
    }
    //开始滴水
    startDropWater() {
        console.log('开始创建水')
        this.schedule(this.createWater, 0.1)
    }
    createWater() {
        if (this.waterCount < this.totalWater) {
            this.waterCount++

            var ball = cc.instantiate(this.Ball);
            ball.x = this.waterPipe.x + Math.random() * 8 - 16
            ball.y = this.waterPipe.y + Math.random() * 5 - 75
               // ball.getComponent(cc.RigidBody).linearVelocity = cc.v2(0, -380)
            ball.getComponent(cc.PhysicsCircleCollider).density=1
            this.waterContainer.addChild(ball, -1)
            this.waters.push(ball);
            this.waterSoundDelayCount+=0.1
            if(this.waterSoundDelayCount>this.waterSoundDelay)
            {
                this.waterSoundDelayCount=0
                cc.audioEngine.playEffect(this.waterClip,false)
            }
        } else {
            this.unschedule(this.createWater)
            this.schedule(this.checkWin,0.1)
        }

    }
    checkWin()
    {
        if(this.over)return
        var bol=true
        for(var water of this.waters)
        {
            if(water.getComponent(cc.RigidBody).awake)
            {
                bol=false
                break;
            }
        }
        if(bol)
        {
            this.gameWin();
        }
    }
    onBeginContact(contact, selfCollider, otherCollider) {
        if (selfCollider.node.name == 'ground' && otherCollider.node.name == 'Ball' &&!this.over) {            
            this.gameLose()       
        }
    }
    showFace(type: number) {
        this.cup.getChildByName('facenormal').active = false;
        this.cup.getChildByName('facewin').active = false;
        this.cup.getChildByName('facelose').active = false;
        if (type == 2) {
            this.cup.getChildByName('facewin').active = true;
        } else if (type == 1) {
            this.cup.getChildByName('facelose').active = true;
        } else if (type == 0) {
            this.cup.getChildByName('facenormal').active = true;
        }
    }
    update(dt) {
        if (this.waterCount > 0) {
            this.metaBall.getComponent(MetaballMgr).draw()
        }
    }
    gameWin()
    {
        Model.game.dragLevel++
        this.unscheduleAllCallbacks()
        this.over=true
        Model.game.win=true
        this.showFace(2)
        this.scheduleOnce(this.delayShowEnd, 1) 
    }
    gameLose()
    {
        this.unscheduleAllCallbacks()
        this.over=true
        Model.game.win=false
        this.showFace(1)
        this.scheduleOnce(this.delayShowEnd, 1) 
    }
    delayShowEnd() {
        cc.director.loadScene('gameEnd')
    }
}
